package org.springbus.ff.animate;

import com.google.common.collect.Lists;
import org.springbus.ff.conf.FFBaseConf;
import org.springbus.ff.filter.Pos;
import org.springbus.ff.node.FFNode;

import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class Effects {
    private static final String target = "_target_";
    private static final String targetLeft = "_target_left_";
    private static final String targetRight = "_target_right_";
    private static final String targetUp = "_target_up_";
    private static final String targetBottom = "_target_bottom_";
    private static final String targetLeftBig = "_target_left_big_";
    private static final String targetRightBig = "_target_right_big_";
    private static final String targetUpBig = "_target_up_big_";
    private static final String targetBottomBig = "_target_bottom_big_";
    private static final String targetRotate = "_target_rotate_";
    private static final String targetRotateAdd = "_target_rotate_add_";
    private static final String targetRotateAddBig = "_target_rotate_add_big_";
    private static final String zoomBig = "_zoom_big_";
    private static final String zoomBiging = "_zoom_biging_";
    private static final String targetSize = "_target_size_";

    private static final float time = 3f;
    private static final float inDelay = 0;
    private static final float outDelay = 5;
    private static final float zoomingSpeed = 0.005f;
    private static final float moveingSpeed = 50f;

    public static FFBaseConf ins = new FFBaseConf("in", time, inDelay, false);
    public static FFBaseConf outs = new FFBaseConf("out", time, outDelay, false);
    public static FFBaseConf ingins = new FFBaseConf("in", 60 * 60f, inDelay, true);
    public static FFBaseConf ingouts = new FFBaseConf("out", 60 * 60f, outDelay, true);


    static Map<String, ArrayList<FFBaseConf>> effects = new HashMap<>();

    static {
        // no

        // no: { type: 'move', ...ins, from: target, to: target, name: 'no' };
        effects.put("no", Lists.newArrayList(new FFBaseConf("move", ins, target, target, "no")));
        // show: { type: 'move', ...ins, from: target, to: target, name: 'no' },
        effects.put("show", Lists.newArrayList(new FFBaseConf("move", ins, target, target, "no")));

        // fade
        effects.put("fadeIn", Lists.newArrayList(new FFBaseConf("show", ins)));
        // fadeIn: { type: 'show', ...ins },
        // fadeOut: { type: 'show', ...outs },
        effects.put("fadeOut", Lists.newArrayList(new FFBaseConf("show", outs)));

        // move normal
//       moveInLeft: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetLeft, to: target, ease: 'quadOut' },
//  ]
        effects.put("moveInLeft", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetLeft, target, null, "quadOut")

        ));
//       moveOutLeft: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetLeft, ease: 'quadIn' },
//  ],
        effects.put("moveOutLeft", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetLeft, null, "quadIn")

        ));

//       moveInRight: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetRight, to: target, ease: 'quadOut' },
//  ]
        effects.put("moveInRight", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetRight, target, null, "quadOut")

        ));

//       moveOutRight: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetRight, ease: 'quadIn' },
//  ]
        effects.put("moveOutRight", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetRight, null, "quadIn")

        ));
//       moveInUp: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetUp, to: target, ease: 'quadOut' },
//  ]
        effects.put("moveInUp", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetUp, target, null, "quadOut")

        ));
//       moveOutUp: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetUp, ease: 'quadIn' },
//  ],
        effects.put("moveOutUp", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetUp, null, "quadIn")

        ));
//       moveInBottom: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetBottom, to: target, ease: 'quadOut' },
//  ],
        effects.put("moveInBottom", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetBottom, target, null, "quadOut")

        ));

//       moveOutBottom: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetBottom, ease: 'quadIn' },
//  ]
        effects.put("moveOutBottom", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetBottom, null, "quadIn")

        ));

        // move big
//       moveInLeftBig: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetLeftBig, to: target, ease: 'quadOut' },
//  ]
        effects.put("moveInLeftBig", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetLeftBig, target, null, "quadOut")

        ));
//       moveOutLeftBig: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetLeftBig, ease: 'quadIn' },
//  ],
        effects.put("moveOutLeftBig", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetLeftBig, null, "quadIn")

        ));
//       moveInRightBig: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetRightBig, to: target, ease: 'quadOut' },
//  ],
        effects.put("moveInRightBig", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetRightBig, target, null, "quadOut")

        ));
//       moveOutRightBig: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetRightBig, ease: 'quadIn' },
//  ],
        effects.put("moveOutRightBig", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetRightBig, null, "quadIn")

        ));
//       moveInUpBig: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetUpBig, to: target, ease: 'quadOut' },
//  ],
        effects.put("moveInUpBig", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetUpBig, target, null, "quadOut")

        ));

//       moveOutUpBig: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetUpBig, ease: 'quadIn' },
//  ],
        effects.put("moveOutUpBig", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetUpBig, null, "quadIn")

        ));
        //  moveInBottomBig: [
        //       { type: 'show', ...ins },
        //       { type: 'move', ...ins, from: targetBottomBig, to: target, ease: 'quadOut' },
        //  ],
        effects.put("moveInBottomBig", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetBottomBig, target, null, "quadOut")

        ));

//       moveOutBottomBig: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetBottomBig, ease: 'quadIn' },
//  ],
        effects.put("moveOutBottomBig", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetBottomBig, null, "quadIn")

        ));

        // move ease back
//       moveInLeftBack: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetLeftBig, to: target, ease: 'backOut' },
//  ],
        effects.put("moveInLeftBack", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, targetLeftBig, target, null, "backOut")

        ));
//       moveOutLeftBack: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetLeftBig, ease: 'backIn' },
//  ],
        effects.put("moveOutLeftBack", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetLeftBig, null, "backIn")

        ));
//       moveInRightBack: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetRightBig, to: target, ease: 'backOut' },
//  ]
        effects.put("moveInRightBack", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetRightBig, target, null, "backOut")

        ));
//       moveOutRightBack: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetRightBig, ease: 'backIn' },
//  ],
        effects.put("moveOutRightBack", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetRightBig, null, "backIn")

        ));
//       moveInUpBack: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetUpBig, to: target, ease: 'backOut' },
//  ],
        effects.put("moveInUpBack", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, targetUpBig, target, null, "backOut")

        ));
//       moveOutUpBack: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetUpBig, ease: 'backIn' },
//  ],
        effects.put("moveOutUpBack", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetUpBig, null, "backIn")

        ));
//       moveInBottomBack: [
//       { type: 'show', ...ins },
//       { type: 'move', ...ins, from: targetBottomBig, to: target, ease: 'backOut' },
//  ],

        effects.put("moveInBottomBack", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetBottomBig, target, null, "backOut")

        ));
//       moveOutBottomBack: [
//       { type: 'show', ...outs },
//       { type: 'move', ...outs, from: target, to: targetBottomBig, ease: 'backIn' },
//  ],
        effects.put("moveOutBottomBack", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("move", outs, target, targetBottomBig, null, "backIn")

        ));

        // rotate in out
//       rotateIn: [
//       { type: 'show', ...ins },
//       { type: 'rotate', ...ins, from: targetRotateAdd, to: targetRotate, ease: 'linear' },
//  ],
        effects.put("rotateIn", Lists.newArrayList(
                new FFBaseConf("show", ins),
                new FFBaseConf("move", ins, targetRotateAdd, targetRotate, null, "linear")

        ));
//       rotateOut: [
//       { type: 'show', ...outs },
//       { type: 'rotate', ...outs, from: targetRotate, to: targetRotateAdd, ease: 'quadIn' },
//  ],
        effects.put("rotateOut", Lists.newArrayList(
                new FFBaseConf("outs", outs),
                new FFBaseConf("rotate", outs, targetRotate, targetRotateAdd, null, "quadIn")

        ));
//       rotateInBig: [
//       { type: 'show', ...ins },
//       { type: 'rotate', ...ins, from: targetRotateAddBig, to: targetRotate, ease: 'quadOut' },
//  ],
        effects.put("rotateInBig", Lists.newArrayList(
                new FFBaseConf("outs", ins),
                new FFBaseConf("rotate", ins, targetRotateAddBig, targetRotate, null, "quadOut")

        ));
//       rotateOutBig: [
//       { type: 'show', ...outs },
//       { type: 'rotate', ...outs, from: targetRotate, to: targetRotateAddBig, ease: 'quadIn' },
//  ],
        effects.put("rotateOutBig", Lists.newArrayList(
                new FFBaseConf("show", outs),
                new FFBaseConf("rotate", outs, targetRotate, targetRotateAddBig, null, "quadIn")

        ));

        // zoom in out
//       zoomIn: [
//       { type: 'zoom', ...ins, from: 1 / 2, to: 1, size: targetSize, pad: true },
//       { type: 'show', ...ins },
//  ],
        effects.put("zoomIn", Lists.newArrayList(
                new FFBaseConf("zoom", ins, (1.0f / 2f), 1f, targetSize, true),
                new FFBaseConf("show", ins)

        ));
//       zoomOut: [
//       { type: 'zoom', ...outs, from: 2, to: 1, size: targetSize, pad: true },
//       { type: 'show', ...outs },
//  ],
        effects.put("zoomOut", Lists.newArrayList(
                new FFBaseConf("zoom", outs, 2f, 1f, targetSize, true),
                new FFBaseConf("show", outs)

        ));
//       zoomNopadIn: [
//       { type: 'zoom', ...ins, from: 1.5, to: 1, size: targetSize },
//       { type: 'show', ...ins },
//  ],
        effects.put("zoomNopadIn", Lists.newArrayList(
                new FFBaseConf("zoom", ins, 1.5f, 1f, targetSize, false),
                new FFBaseConf("show", ins)

        ));
//       zoomNopadOut: [
//       { type: 'zoom', ...outs, from: 1, to: 1.5, size: targetSize },
//       { type: 'show', ...outs },
//  ],
        effects.put("zoomNopadOut", Lists.newArrayList(
                new FFBaseConf("zoom", outs, 1f, 1.5f, targetSize, false),
                new FFBaseConf("show", outs)

        ));
//       zoomInUp: [
//       { type: 'zoom', ...ins, from: 1, to: 2, size: targetSize, pad: true },
//       { type: 'move', ...ins, from: targetUp, to: target, ease: 'quadOut' },
//       { type: 'show', ...ins },
//  ],

        effects.put("zoomInUp", Lists.newArrayList(
                new FFBaseConf("zoom", ins, 1f, 2f, targetSize, true),
                new FFBaseConf("move", ins, targetUp, target, null, "quadOut"),
                new FFBaseConf("show", ins)

        ));
//       zoomOutUp: [
//       { type: 'zoom', ...outs, from: 2, to: 1, size: targetSize, pad: true },
//       { type: 'move', ...outs, from: target, to: targetUp },
//       { type: 'show', ...outs },
//  ],

        effects.put("zoomOutUp", Lists.newArrayList(
                new FFBaseConf("zoom", outs, 2f, 1f, targetSize, true),
                new FFBaseConf("move", outs, target, targetUp, null, null),
                new FFBaseConf("show", outs)

        ));
//       zoomInDown: [
//       { type: 'zoom', ...ins, from: 1, to: 2, size: targetSize, pad: true },
//       { type: 'move', ...ins, from: targetBottom, to: target, ease: 'quadOut' },
//       { type: 'show', ...ins },

        effects.put("zoomInDown", Lists.newArrayList(
                new FFBaseConf("zoom", ins, 1f, 2f, targetSize, true),
                new FFBaseConf("move", ins, targetBottom, target, null, "quadOut"),
                new FFBaseConf("show", ins)

        ));
//  ],
//       zoomOutDown: [
//       { type: 'zoom', ...outs, from: 2, to: 1, size: targetSize, pad: true },
//       { type: 'move', ...outs, from: target, to: targetBottom },
//       { type: 'show', ...outs },
//  ],
        effects.put("zoomOutDown", Lists.newArrayList(
                new FFBaseConf("zoom", outs, 2f, 1f, targetSize, true),
                new FFBaseConf("move", outs, target, targetBottom, null, null),
                new FFBaseConf("show", outs)

        ));

        // background effect ing,,,
        // zoomingIn: [{ type: 'zoom', ...ingins, from: 1, add: zoomingSpeed, size: targetSize }],
        effects.put("zoomingIn", Lists.newArrayList(new FFBaseConf("move", ingins, 1f, zoomingSpeed, targetSize)));
        //zoomingOut: [{ type: 'zoom', ...ingins, from: 2, add: -zoomingSpeed, size: targetSize }],
        effects.put("zoomingOut", Lists.newArrayList(new FFBaseConf("move", ingins, 2f, zoomingSpeed, targetSize)));
        // moveingLeft: [{ type: 'move', ...ingins, from: target, add: { x: -moveingSpeed, y: 0 } }],
        effects.put("moveingLeft", Lists.newArrayList(new FFBaseConf("move", ingins, target, new Pos((int) -moveingSpeed, 0))));
        // moveingRight: [{ type: 'move', ...ingins, from: target, add: { x: moveingSpeed, y: 0 } }],
        effects.put("moveingRight", Lists.newArrayList(new FFBaseConf("move", ingins, target, new Pos((int) moveingSpeed, 0))));
        //moveingUp: [{ type: 'move', ...ingins, from: target, add: { x: 0, y: -moveingSpeed } }],
        effects.put("moveingUp", Lists.newArrayList(new FFBaseConf("move", ingins, target, new Pos(0, (int) -moveingSpeed))));
        // moveingBottom: [{ type: 'move', ...ingins, from: target, add: { x: 0, y: moveingSpeed } }],
        effects.put("moveingBottom", Lists.newArrayList(new FFBaseConf("move", ingins, target, new Pos(0, (int) moveingSpeed))));
        // fadingIn: { type: 'show', ...ingins },
        // fadingOut: { type: 'show', ...ingouts },
        effects.put("fadingIn", Lists.newArrayList(new FFBaseConf("show", ingins)));
        effects.put("fadingOut", Lists.newArrayList(new FFBaseConf("show", ingouts)));


    }

    ;


    public static Pos mapping(String key, FFNode obj) {
        Pos val = null;
        int minDis = 100;
        int maxDis = 400;

        switch (key) {
            case target:
                val = new Pos(obj.x, obj.y);
                break;
            // up / down/ left/ right
            case targetLeft:
                val = new Pos(obj.x - minDis, obj.y);
                break;
            case targetRight:
                val = new Pos(obj.x + minDis, obj.y);
                break;
            case targetUp:
                val = new Pos(obj.x, obj.y - minDis);
                break;
            case targetBottom:
                val = new Pos(obj.x, obj.y + minDis);
                break;

            // big up / down/ left/ right
            case targetLeftBig:
                val = new Pos(obj.x - maxDis, obj.y);
                break;
            case targetRightBig:
                val = new Pos(obj.x + maxDis, obj.y);
                break;
            case targetUpBig:
                val = new Pos(obj.x, obj.y - maxDis);
                break;
            case targetBottomBig:
                val = new Pos(obj.x, obj.y + maxDis);
                break;

            // rotate
            case targetRotate:
                val = new Pos(obj.rotate);
                break;
            case targetRotateAdd:
                val = new Pos(obj.rotate + 60);
                break;
            case targetRotateAddBig:
                val = new Pos(obj.rotate + 180);
                break;

            // zoom
            case zoomBig:
                val = new Pos();
                val.zoom = 1.5;
                break;
            case zoomBiging:
                val = new Pos();
                val.zoom = 2;
                break;
            case targetSize:
                val = new Pos();
                val.size = obj.getSize();
                break;
        }
        return val;
    }
}